﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Com.Mapabc.Maps.Api.BaseTypes;
using Com.Mapabc.Maps.Api.Overlays;
using Com.Mapabc.Maps.Api.Events;
using System.Windows.Browser;
using LantinxShare.LBS.Location;
using LantixLBSServer.Common;

namespace LantixLBSServer
{
    public partial class MainPage : UserControl
    {
        private List<GLocation> list = new List<GLocation>();
        private double amendedLatitude = -0.002;
        private double amendedLongtude = 0.004;
        private String downLoadURL = string.Empty;
        private bool isAmendedb = false;

        public MainPage()
        {
            InitializeComponent();
            this.mapZoom.ValueChanged += new RoutedPropertyChangedEventHandler<double>(slidermapZoom);
            this.map.Map_Loaded += MainPage_Loaded;
        }
        private String GetBasePath()
        {
            String basePath = string.Empty;
            if (Application.Current.Host.Source.Port == 80)
            {
                basePath = string.Format("{0}://{1}/", Application.Current.Host.Source.Scheme, Application.Current.Host.Source.Host);
            }
            else
            {
                basePath = string.Format("{0}://{1}:{2}/", Application.Current.Host.Source.Scheme, Application.Current.Host.Source.Host, Application.Current.Host.Source.Port);

            }
            return basePath;
        }

        public void MainPage_Loaded(object obj, MapEventArgs args)
        {
            map.Mouse_Click += Map_MouseClick;

        }

        void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            try
            {
                string result = e.Result;
                if (!string.IsNullOrEmpty(result))
                {
                    string[] addressArray = result.Split('|');
                    if (addressArray != null)
                    {
                        list.Clear();
                        map.CloseTip();

                        int zoom = int.Parse(mapZoomValue.Text);

                        list.AddRange(GetAddressList(result));
                        if (list.Count == 1)
                        {
                            MoveTo(list[0].Location.Longitude, list[0].Location.Latitude, zoom);
                        }
                        else
                        {
                            MLngLatBounds bounds = SetExtent(list, true);
                            map.LngLatBounds = bounds;
                            int zoom2 = this.GetZoom(bounds.NorthEast, bounds.SouthWest);
                            map.SetZoomAndCenter(zoom2, GetCenter(bounds.NorthEast, bounds.SouthWest));

                        }
                        DrawAddressList(list);
                    }
                }
            }
            catch (Exception ex)
            {
                ShowError(downLoadURL);
            }
        }


        private IList<GLocation> GetAddressList(string result)
        {
            IList<GLocation> list = new List<GLocation>();
            if (!string.IsNullOrEmpty(result))
            {
                string[] addressArray = result.Split('|');
                if (addressArray != null)
                {
                    foreach (var item in addressArray)
                    {
                        string[] addressGroup = item.Split(',');
                        if (addressGroup != null && addressGroup.Length >= 2)
                        {
                            DateTime cDateStamp = DateTime.Now;
                            if (addressGroup.Length > 3)
                            {
                                try
                                {
                                    String c = addressGroup[3];
                                    cDateStamp = new DateTime(
                                        int.Parse(c.Substring(0, 4)),
                                        int.Parse(c.Substring(4, 2)),
                                        int.Parse(c.Substring(6, 2)),
                                        int.Parse(c.Substring(8, 2)),
                                        int.Parse(c.Substring(10,2)), 0);
                                }
                                catch (Exception ex)
                                {

                                }
                            }
                            list.Add(new GLocation()
                            {
                                Location = new GPoint(double.Parse(addressGroup[1]) + amendedLongtude,
                                    double.Parse(addressGroup[2]) + amendedLatitude),
                                Title = addressGroup[0],
                                GTimeStamp = cDateStamp
                            });

                        }
                    }

                }
            }
            return list;
        }

        private void Map_MouseClick(object obj, MapMouseEventArgs args)
        {
            MLngLat xy = args.CenterXY;
            LngX.Text = xy.X.ToString();
            LatY.Text = xy.Y.ToString();
        }
        private void slidermapZoom(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            this.mapZoomValue.Text = "" + ((int)(this.mapZoom.Value));
        }
        private void MsetZoomAndCenter(object sender, RoutedEventArgs e)
        {
            int zoom = int.Parse(mapZoomValue.Text);
            //double centerLng = double.Parse(mapLngX.Text);
            //double centerLat = double.Parse(mapLatY.Text);
            //map.SetZoomAndCenter(zoom, new MLngLat(centerLng, centerLat));
            MoveTo(double.Parse(mapLngX.Text), double.Parse(mapLatY.Text), zoom);
        }

        private void MoveTo(double longtitude, double latitude, int zoom)
        {
            double centerLng = double.Parse(mapLngX.Text);
            double centerLat = double.Parse(mapLatY.Text);
            map.SetZoomAndCenter(zoom, new MLngLat(centerLng, centerLat));
        }

        private MLngLatBounds SetExtent(IList<GLocation> list, bool hasBuffer)
        {
            var location = list[0].Location;
            double east = location.Longitude;
            double west = location.Longitude;
            double south = location.Latitude;
            double north = location.Latitude;
            foreach (var item in list)
            {
                var locationItem = item.Location;
                #region
                if (locationItem.Longitude < west)
                {
                    west = locationItem.Longitude;
                }
                if (locationItem.Longitude > east)
                {
                    east = locationItem.Longitude;
                }
                if (locationItem.Latitude < south)
                {
                    south = locationItem.Latitude;
                }
                if (locationItem.Latitude > north)
                {
                    north = locationItem.Latitude;
                }
                #endregion
            }
            if (hasBuffer)
            {
                int zoom = this.GetZoom(new MLngLat(west, south), new MLngLat(east, north));
                return new MLngLatBounds(west - GetBuffer(zoom), south - GetBuffer(zoom), east + GetBuffer(zoom), north + GetBuffer(zoom));
            }
            else
            {
                return new MLngLatBounds(west, south, east, north);
            }
        }

        private void DrawImage(GLocation address, String title)
        {
            MLngLat mpoint = GLocationHelper.GPointToMLngLat(address.Location);
            MMarker marker = new MMarker(mpoint)
            {

                IconURL = GetBasePath() + (isAmendedb ? "images/golf.png" : "images/lan_1.png"),
                IconWidth = 23,
                IconHeight = 32,
                CanShowTip = true,

                Tip = new MTip()
                {
                    Title = "标题:" + address.Title,
                    Content ="时间:"+address.GTimeStamp.ToString("yyyy-MM-dd HH:mm")+"\n位置:\n"+ mpoint.X + "\n" + mpoint.Y,
                    Width = 200,
                    Height = 150
                }
            };
            map.AddOverlay(marker);
        }

        private void DrawAddressList(IList<GLocation> pointList)
        {
            foreach (var item in pointList)
            {
                DrawImage(item, item.ToString());
            }
        }

        private double GetBuffer(int level)
        {
            double buffer = 1;

            switch (level)
            {
                case 1:
                    buffer = 20;
                    break;
                case 2:
                case 3:
                    buffer = 10;
                    break;
                case 4:
                case 5:
                    buffer = 5;
                    break;

                case 6:
                case 7:
                    buffer = 1;
                    break;
                case 8:
                case 9:
                    buffer = 0.1;
                    break;
                case 10:
                case 11:
                    buffer = 0.08;
                    break;

                case 12:
                    buffer = 0.005;
                    break;
                case 13:
                    buffer = 0.002;
                    break;
                case 14:
                case 15:
                    buffer = 0.001;
                    break;
                case 16:
                case 17:
                    buffer = 0.0005;
                    break;
            }
            return buffer;
        }

        private void ShowError(String msg)
        {
            MessageBox.Show(msg);
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                isAmendedb = false;
                amendedLatitude = 0;
                amendedLongtude = 0;
                map.RemoveAllOverlays();
                GetData();
            }
            catch (Exception ex)
            {
                ShowError(downLoadURL);
            }
        }

        private void GetData()
        {
            WebClient wc = new WebClient();
            String basePath = GetBasePath();
            Random random = new Random(DateTime.Now.Second);
            downLoadURL = basePath + "AddressPage.aspx?option=getall&random=" + random.NextDouble();

            //downLoadURL = "http://www.echotian.com/echo/AddressPage.aspx?option=getall";
            wc.DownloadStringAsync(new Uri(downLoadURL, UriKind.Absolute));
            wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wc_DownloadStringCompleted);
        }

        private int GetZoom(MLngLat lng, MLngLat lat)
        {
            double x = Math.Abs(lng.X - lat.X);
            double y = Math.Abs(lng.Y - lat.Y);
            int zoom = 1;
            double k = Math.Max(x, y);
            zoom = (k < 100) ? zoom = 2 : zoom;
            zoom = (k < 50) ? zoom = 3 : zoom;
            zoom = (k < 20) ? zoom = 4 : zoom;
            zoom = (k < 10) ? zoom = 5 : zoom;
            zoom = (k < 5) ? zoom = 6 : zoom;
            zoom = (k < 3) ? zoom = 7 : zoom;
            zoom = (k < 2.95) ? zoom = 8 : zoom;
            zoom = (k < 2.9) ? zoom = 9 : zoom;
            zoom = (k < 1.7) ? zoom = 10 : zoom;
            zoom = (k < 1.5) ? zoom = 11 : zoom;
            zoom = (k < 1.2) ? zoom = 12 : zoom;
            zoom = (k < 1) ? zoom = 13 : zoom;
            zoom = (k < 0.2) ? zoom = 14 : zoom;
            zoom = (k < 0.15) ? zoom = 15 : zoom;
            zoom = (k < 0.1) ? zoom = 16 : zoom;
            zoom = (k < 0.01) ? zoom = 17 : zoom;
            return zoom;
        }

        private MLngLat GetCenter(MLngLat lng, MLngLat lat)
        {
            return new MLngLat((lng.X + lat.X) / 2.0D, (lng.Y + lat.Y) / 2.0D);
        }

        private void btnAmended_Click(object sender, RoutedEventArgs e)
        {
            isAmendedb = true;
            string amendedValue = this.txtAmended.Text.Trim();
            if (!string.IsNullOrEmpty(amendedValue))
            {
                try
                {
                    string[] amendedValueList = amendedValue.Split(',');
                    amendedLongtude = double.Parse(amendedValueList[0]);
                    amendedLatitude = double.Parse(amendedValueList[1]);
                }
                catch
                {
                    ShowError("请输入格式正确格式的校正值: 121.00,31.0");
                }
            }
            GetData();
        }
    }// end for class

    //public class GLocation
    //{
    //    public MLngLat Location { get; set; }
    //    public String Title { get; set; }

    //    public DateTime GTimeStamp { get; set; }
    //    public override string ToString()
    //    {
    //        return Title + "," + Location.X + "," + Location.Y + "," + GTimeStamp.ToString("yyyyMMddHHmmss");
    //    }
    //}
}
